#pragma once
#include <string>
#include <vector>
#include <assert.h>
#include <fstream>
#include "../Comm/Log.hpp"
#include "../Comm/Util.hpp"
#include <unordered_map>
#include "include/mysql/jdbc.h"

namespace model_ns
{

    using namespace Log_ns;
    using namespace util_ns;

    struct Question
    {
        std::string number; // 题目编号
        std::string title;  // 题目名
        std::string level;  // 题目难度
        int cpu_limit;
        int mem_limit;
        std::string desc;   // 题目的内容/描述
        std::string header; // 给用户的编写代码区域
        std::string tail;   // 测试用例，最终要与用户返回的代码拼接在一起，交给后台的编译运行服务
    };

    const static std::string path = "./Questions/Questions.list"; // 题目列表文件路径
    const static std::string comm = "./Questions/";               // 文件的公共目录

    const static int port = 3306;
    const static std::string schem = "oj";//哪个数据库
    const static std::string hostname = "127.0.0.1";//ip地址/url
    const static std::string passward = "123456";//ip地址/url
    const static std::string username = "oj_client";//ip地址/url
    const static std::string tablename = "questions";

    // 1.给Control提供对题库增删查改的功能
    class Model
    {
    private:
        std::unordered_map<std::string, Question *> questions;

    public:
        Model()
        {
        }
        ~Model() {}

    public:
        bool GetQuery(const std::string &sql, std::vector<Question *> *out)
        {
            LOG(INFO) << "开始连接数据库了... " << "\n";
            // 1.连接数据库
            sql::mysql::MySQL_Driver *driver;
            sql::Connection *con;
            sql::ConnectOptionsMap connection_detail;
            sql::Statement* st;
            sql::ResultSet* res;
            connection_detail[OPT_PORT] = port;
            connection_detail[OPT_SCHEMA] = schem;
            connection_detail[OPT_HOSTNAME] = hostname;
            connection_detail[OPT_PASSWORD] = passward;
            connection_detail[OPT_USERNAME] = username;
            connection_detail[OPT_CHARSET_NAME] = "utf8mb4";//客户端和服务器之间的所有通信（双向）。
            connection_detail[OPT_RECONNECT] = true;//设置该连接的编码格式

            //初始化driver
            driver = sql::mysql::get_mysql_driver_instance();

            if(!(con = driver->connect(connection_detail)))
            {
                LOG(FATAL) << "连接数据库失败,检查参数..." << "\n";
                return false;
            }

            LOG(INFO) << "连接数据库成功..." << "\n";

            st = con->createStatement();
            assert(st);

            res = st->executeQuery(sql);
            assert(res);

            while(res->next())
            {
                LOG(INFO) << "拿到一行数据了" << "\n";
                Question* question = new Question;
                question->number = res->getString("number");
                question->desc = res->getString("question_desc");
                question->header = res->getString("header");
                question->tail = res->getString("tail");
                question->level = res->getString("star");
                question->mem_limit = res->getInt("mem_limit");
                question->cpu_limit = res->getInt("cpu_limit");
                question->title = res->getString("title");

                (*out).emplace_back(question);
            }

            delete st;
            delete con;
            delete res;
            return true;
        }
        // 读取所有题目的内容
        bool GetAllQuestions(std::vector<Question *> *out)
        {
            LOG(INFO) << "bool GetAllQuestions(std::vector<Question *> *out)..." << "\n";
            std::string sql = "select * from ";
            sql += tablename;

            return GetQuery(sql,out);
        }

        // 获取一个题目的信息
        bool GetOneQuestion(const std::string &number, Question **question)
        {
            LOG(INFO) << "bool GetOneQuestion(const std::string &number, Question **question)" << "\n";
            std::string sql = "select * from ";
            sql += tablename;
            sql += " where number=";
            sql += number;
            
            std::vector<Question*> res;
            if(GetQuery(sql,&res))
            {
                *question = res[0];
                return true;
            }

            return false;
        }
    };

//    enum Operation
//    {
//        ADD = 1,
//        DEL,
//        QUERY
//    };
//
//    using user_t = std::string;
//    class User
//    {
//        private:
//            bool MysqlCrl(const user_t& user,int op)//同时提供查询、删除、增加用户的功能
//            {
//                //0.连接数据库
//                sql::mysql::MySQL_Driver *driver;
//                sql::Connection *con;
//                sql::ConnectOptionsMap connection_detail;
//                sql::Statement* st;
//                sql::ResultSet* res;
//                connection_detail[OPT_PORT] = port;//mysqld的端口号
//                connection_detail[OPT_SCHEMA] = schem;//数据库名称
//                connection_detail[OPT_HOSTNAME] = hostname;//ip地址
//                connection_detail[OPT_PASSWORD] = passward;//用户密码
//                connection_detail[OPT_USERNAME] = username;//用户名
//                connection_detail[OPT_CHARSET_NAME] = "utf8mb4";//客户端和服务器之间的所有通信（双向）。
//                connection_detail[OPT_RECONNECT] = true;//设置自动重连标志
//    
//                //初始化driver
//                driver = sql::mysql::get_mysql_driver_instance();
//    
//                if(!(con = driver->connect(connection_detail)))
//                {
//                    LOG(FATAL) << "连接数据库失败,检查参数..." << "\n";
//                    return false;
//                }
//    
//                LOG(INFO) << "连接数据库成功..." << "\n";
//                //1.根据op执行不同的操作
//                switch (op)
//                {
//                case Operation::ADD:
//                    /*从数据库中添加新的用户*/
//                    
//                    break;
//                case Operation::DEL:
//                    /*从数据库中删除用户*/
//                    break;
//                case Operation::QUERY :
//                    /*查询相关用户是否存在*/
//                default:
//                    break;
//                }
//            }
//        public:
//            bool AddUser(const std::string& username,const std::string& passwd)
//            {
//                //0.通过成熟的哈希算法现将用户输入的账号和密码转化为一个唯一值
//
//
//                //1.将这个值插入用户表（User)中,返回插入的结果，给User表的id字段添加约束
//            }
//
//            bool DelUser(const std::string& username,const std::string& passwd);
//
//            bool IsExist(const user_t& user)
//            {
//                //0.查询浏览器session返回的user是否存在于数据库中
//            }
//    };
}
